﻿@page "/administration"
@using Microsoft.AspNetCore.Authorization;
@using Microsoft.AspNetCore.Identity;
@using BlazorOrdering.Web.Entry.Areas.Identity.Data;
@inject UserManager<BlazorOrderingUser> _UserManager
@inject RoleManager<IdentityRole> _RoleManager
@inject AuthenticationStateProvider AuthenticationStateProvider
<h3>Simple Blazor User and Role Manager</h3>
<h4>超简单的用户管理后台</h4>
<AuthorizeView>
    <Authorized>
        @if (@context.User.IsInRole(ADMINISTRATION_ROLE))
        {
            <p>You are in @ADMINISTRATION_ROLE </p>
            <table class="table">
                <thead>
                    <tr>
                        <th>Id</th>
                        <th>User Name</th>
                        <th>昵称</th>
                        <th>Email</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var user in ColUsers)
                    {
                    <tr>
                        <td>@user.Id.Substring(0, 5) ...</td>
                        <td>@user.UserName</td>
                        <td>@user.CustomName</td>
                        <td>@user.Email</td>
                        <td>
                            <!-- Edit the current forecast -->
                            <button class="btn btn-primary"
                                    @onclick="(() => EditUser(user))">
                                编辑
                            </button>
                        </td>
                    </tr>
                    }
                </tbody>
            </table>
            @if (ShowPopup)
            {
                <!-- This is the popup to create or edit a user -->
                <div class="modal" tabindex="-1" style="display:block" role="dialog">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h3 class="modal-title">Edit User</h3>
                                <!-- Button to close the popup -->
                                <button type="button" class="close"
                                        @onclick="ClosePopup">
                                    <span aria-hidden="true">X</span>
                                </button>
                            </div>
                            <!-- Edit form for the current user -->
                            <div class="modal-body">
                                <!-- Only show Id if not a new user -->
                                @if (objUser.Id != "")
                                {
                                    <p>@objUser.Id</p>
                                }
                                <!-- Only allow edit if a new user -->
                                @if (objUser.Id != "")
                                {
                                    <p>@objUser.UserName</p>
                                }
                                else
                                {
                                    <input class="form-control" type="text"
                                           placeholder="UserName"
                                           @bind="objUser.UserName" />
                                }
                                <input class="form-control" type="text"
                                       placeholder="Email"
                                       @bind="objUser.Email" />
                                <input class="form-control" type="text"
                                       placeholder="CustomName"
                                       @bind="objUser.CustomName" />
                                <input class="form-control" type="password"
                                       placeholder="Password"
                                       @bind="objUser.PasswordHash" />
                                <select class="form-control"
                                        @bind="@CurrentUserRole">
                                    @foreach (var option in Options)
                                    {
                                        <option value="@option">
                                            @option
                                        </option>
                                    }
                                </select>
                                <br /><br />
                                <!-- Button to save the user -->
                                <button class="btn btn-primary"
                                        @onclick="SaveUser">
                                    Save
                                </button>
                                <!-- Only show delete button if not a new record -->
                                @if (objUser.Id != "")
                                {
                                    <!-- Button to delete the forecast -->
                                    <button class="btn btn-danger"
                                            @onclick="DeleteUser">
                                        Delete
                                    </button>
                                }
                                <br />
                                <span style="color:red">@strError</span>
                            </div>
                        </div>
                    </div>
                </div>
            }

            <button class="btn btn-success" @onclick="AddNewUser">添加用户</button>

        }
        else
        {
            <p>You're not signed in as a user in @ADMINISTRATION_ROLE.</p>
        }
    </Authorized>
    <NotAuthorized>
        <p>You're not loggged in.</p>
    </NotAuthorized>
</AuthorizeView>
@code {
    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }
    string ADMINISTRATION_ROLE = "Administrators";
    System.Security.Claims.ClaimsPrincipal CurrentUser;


    // Property used to add or edit the currently selected user
    BlazorOrderingUser objUser = new BlazorOrderingUser();
    // Tracks the selected role for the currently selected user
    string CurrentUserRole { get; set; } = "Users";
    // Collection to display the existing users
    List<BlazorOrderingUser> ColUsers = new List<BlazorOrderingUser>();
    // Options to display in the roles dropdown when editing a user
    List<string> Options = new List<string>() { "Users", "Administrators" };
    // To hold any possible errors
    string strError = "";
    // To enable showing the Popup
    bool ShowPopup = false;



    async Task EditUser(BlazorOrderingUser _IdentityUser)
    {
        // Set the selected user
        // as the current user
        objUser = _IdentityUser;
        // Get the user
        var user = await _UserManager.FindByIdAsync(objUser.Id);
        if (user != null)
        {
            // Is user in administrator role?
            var UserResult =
                await _UserManager
                .IsInRoleAsync(user, ADMINISTRATION_ROLE);
            if (UserResult)
            {
                CurrentUserRole = ADMINISTRATION_ROLE;
            }
            else
            {
                CurrentUserRole = "Users";
            }
        }
        // Open the Popup
        ShowPopup = true;
    }

    async Task DeleteUser()
    {
        // Close the Popup
        ShowPopup = false;
        // Get the user
        var user = await _UserManager.FindByIdAsync(objUser.Id);
        if (user != null)
        {
            // Delete the user
            await _UserManager.DeleteAsync(user);
        }
        // Refresh Users
        GetUsers();
    }

    void ClosePopup()
    {
        // Close the Popup
        ShowPopup = false;
    }
    public void GetUsers()
    {
        // clear any error messages
        strError = "";
        // Collection to hold users
        ColUsers = new List<BlazorOrderingUser>();
        // get users from _UserManager
        var user = _UserManager.Users.Select(x => new BlazorOrderingUser
        {
            Id = x.Id,
            UserName = x.UserName,
            Email = x.Email,
            CustomName=x.CustomName,
            PasswordHash = "*****"
        });
        foreach (var item in user)
        {
            ColUsers.Add(item);
        }
    }

    void AddNewUser()
    {
        // Make new user
        objUser = new BlazorOrderingUser();
        objUser.PasswordHash = "*****";
        // Set Id to blank so we know it is a new record
        objUser.Id = "";
        // Open the Popup
        ShowPopup = true;
    }
    async Task SaveUser()
    {
        try
        {
            // Is this an existing user?
            if (objUser.Id != "")
            {
                // Get the user
                var user = await _UserManager.FindByIdAsync(objUser.Id);
                // Update Email
                user.Email = objUser.Email;
                // Update CustomName
                user.CustomName = objUser.CustomName;

                // Update the user
                await _UserManager.UpdateAsync(user);
                // Only update password if the current value
                // is not the default value
                if (objUser.PasswordHash != "*****")
                {
                    var resetToken =
                        await _UserManager.GeneratePasswordResetTokenAsync(user);
                    var passworduser =
                        await _UserManager.ResetPasswordAsync(
                            user,
                            resetToken,
                            objUser.PasswordHash);
                    if (!passworduser.Succeeded)
                    {
                        if (passworduser.Errors.FirstOrDefault() != null)
                        {
                            strError =
                                passworduser
                                .Errors
                                .FirstOrDefault()
                                .Description;
                        }
                        else
                        {
                            strError = "Pasword error";
                        }
                        // Keep the popup opened
                        return;
                    }
                }
                // Handle Roles
                // Is user in administrator role?
                var UserResult =
                    await _UserManager
                    .IsInRoleAsync(user, ADMINISTRATION_ROLE);
                // Is Administrator role selected 
                // but user is not an Administrator?
                if (
                    (CurrentUserRole == ADMINISTRATION_ROLE)
                    &
                    (!UserResult))
                {
                    // Put admin in Administrator role
                    await _UserManager
                        .AddToRoleAsync(user, ADMINISTRATION_ROLE);
                }
                else
                {
                    // Is Administrator role not selected 
                    // but user is an Administrator?
                    if ((CurrentUserRole != ADMINISTRATION_ROLE)
                        &
                        (UserResult))
                    {
                        // Remove user from Administrator role
                        await _UserManager
                            .RemoveFromRoleAsync(user, ADMINISTRATION_ROLE);
                    }
                }
            }
            else
            {
                // Insert new user
                var NewUser =
                    new BlazorOrderingUser
                    {
                        UserName = objUser.UserName,
                        Email = objUser.Email,
                        CustomName=objUser.CustomName
                    };
                var CreateResult =
                    await _UserManager
                    .CreateAsync(NewUser, objUser.PasswordHash);
                if (!CreateResult.Succeeded)
                {
                    if (CreateResult
                        .Errors
                        .FirstOrDefault() != null)
                    {
                        strError =
                            CreateResult
                            .Errors
                            .FirstOrDefault()
                            .Description;
                    }
                    else
                    {
                        strError = "Create error";
                    }
                    // Keep the popup opened
                    return;
                }
                else
                {
                    // Handle Roles
                    if (CurrentUserRole == ADMINISTRATION_ROLE)
                    {
                        // Put admin in Administrator role
                        await _UserManager
                            .AddToRoleAsync(NewUser, ADMINISTRATION_ROLE);
                    }
                }
            }
            // Close the Popup
            ShowPopup = false;
            // Refresh Users
            GetUsers();
        }
        catch (Exception ex)
        {
            strError = ex.GetBaseException().Message;
        }
    }





    protected override async Task OnInitializedAsync()
    {
        // ensure there is a ADMINISTRATION_ROLE
        var RoleResult = await _RoleManager.FindByNameAsync(ADMINISTRATION_ROLE);
        if (RoleResult == null)
        {
            // Create ADMINISTRATION_ROLE Role
            await _RoleManager.CreateAsync(new IdentityRole(ADMINISTRATION_ROLE));
        }
        // Ensure a user named Admin@BlazorOrdering.com is an Administrator
        var user = await _UserManager.FindByNameAsync("Admin@BlazorOrdering.com");
        if (user != null)
        {
            // Is Admin@BlazorOrdering.com in administrator role?
            var UserResult = await _UserManager.IsInRoleAsync(user, ADMINISTRATION_ROLE);
            if (!UserResult)
            {
                // Put admin in Administrator role
                await _UserManager.AddToRoleAsync(user, ADMINISTRATION_ROLE);
            }
        }
        // Get the current logged in user
        CurrentUser = (await authenticationStateTask).User;
        GetUsers();
    }
}
